# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/grade/report/lib.php
--- moodle/grade/report/lib.php Base (1.30.2.15)
+++ moodle/grade/report/lib.php Locally Modified (Based On 1.30.2.15)
@@ -322,5 +322,71 @@
         $html = '<a href="'.$sort_link .'" title="'.$strsort.'">' . $arrow . '</a>';
         return $html;
     }
+
+    /**
+     * This is a really ugly hack, it will be fixed in 2.0
+     * It optionally blanks out course/category totals if they contain any hidden items
+     * @param string $courseid the course id
+     * @param string $course_item an instance of grade_item
+     * @param string $finalgrade the grade for the course_item
+     * @return string The new final grade
+     */
+    protected function blank_hidden_total($courseid, $course_item, $finalgrade) {
+        global $CFG;
+        static $hiding_affected = null;//array of items in this course affected by hiding
+
+        if( !$hiding_affected ) {
+            $items = grade_item::fetch_all(array('courseid'=>$courseid));
+            $grades = array();
+            $sql = "SELECT g.*
+                      FROM {$CFG->prefix}grade_grades g
+                      JOIN {$CFG->prefix}grade_items gi ON gi.id = g.itemid
+                     WHERE g.userid = {$this->user->id} AND gi.courseid = {$courseid}";
+            if ($gradesrecords = get_records_sql($sql)) {
+                foreach ($gradesrecords as $grade) {
+                    $grades[$grade->itemid] = new grade_grade($grade, false);
 }
+                unset($gradesrecords);
+            }
+            foreach ($items as $itemid=>$unused) {
+                if (!isset($grades[$itemid])) {
+                    $grade_grade = new grade_grade();
+                    $grade_grade->userid = $this->user->id;
+                    $grade_grade->itemid = $items[$itemid]->id;
+                    $grades[$itemid] = $grade_grade;
+                }
+                $grades[$itemid]->grade_item =& $items[$itemid];
+            }
+            $hiding_affected = grade_grade::get_hiding_affected($grades, $items);
+        }
+
+        //if the item definitely depends on a hidden item
+        if (array_key_exists($course_item->id, $hiding_affected['altered'])) {
+            if( !$this->showtotalsifcontainhidden ) {
+                //hide the grade
+                $finalgrade = null;
+            }
+            else {
+                //use reprocessed marks that exclude hidden items
+                $finalgrade = $hiding_affected['altered'][$course_item->id];
+            }
+        } else if (!empty($hiding_affected['unknown'][$course_item->id])) {
+            //not sure whether or not this item depends on a hidden item
+            if( !$this->showtotalsifcontainhidden ) {
+                //hide the grade
+                $finalgrade = null;
+            }
+            else {
+                //use reprocessed marks that exclude hidden items
+                $finalgrade = $hiding_affected['unknown'][$course_item->id];
+            }
+        }
+
+        //unset($hiding_affected);
+        //unset($grades);
+        //unset($items);
+
+        return $finalgrade;
+    }
+}
 ?>
Index: moodle/grade/report/overview/lib.php
--- moodle/grade/report/overview/lib.php Base (1.4.2.7)
+++ moodle/grade/report/overview/lib.php Locally Modified (Based On 1.4.2.7)
@@ -59,6 +59,8 @@
 
         $this->showrank = grade_get_setting($this->courseid, 'report_overview_showrank', !empty($CFG->grade_report_overview_showrank));
 
+        $this->showtotalsifcontainhidden = grade_get_setting($this->courseid, 'report_overview_showtotalsifcontainhidden', !empty($CFG->grade_report_overview_showtotalsifcontainhidden));
+
         // get the user (for full name)
         $this->user = get_record('user', 'id', $userid);
 
@@ -127,44 +129,12 @@
                 if (!$canviewhidden and !is_null($finalgrade)) {
                     if ($course_grade->is_hidden()) {
                         $finalgrade = null;
-
                     } else {
                         // This is a really ugly hack, it will be fixed in 2.0
-                        $items = grade_item::fetch_all(array('courseid'=>$course->id));
-                        $grades = array();
-                        $sql = "SELECT g.*
-                                  FROM {$CFG->prefix}grade_grades g
-                                  JOIN {$CFG->prefix}grade_items gi ON gi.id = g.itemid
-                                 WHERE g.userid = {$this->user->id} AND gi.courseid = {$course->id}";
-                        if ($gradesrecords = get_records_sql($sql)) {
-                            foreach ($gradesrecords as $grade) {
-                                $grades[$grade->itemid] = new grade_grade($grade, false);
+                        $finalgrade = $this->blank_hidden_total($course->id, $course_item, $finalgrade);
                             }
-                            unset($gradesrecords);
                         }
-                        foreach ($items as $itemid=>$unused) {
-                            if (!isset($grades[$itemid])) {
-                                $grade_grade = new grade_grade();
-                                $grade_grade->userid = $this->user->id;
-                                $grade_grade->itemid = $items[$itemid]->id;
-                                $grades[$itemid] = $grade_grade;
-                            }
-                            $grades[$itemid]->grade_item =& $items[$itemid];
-                        }
-                        $hiding_affected = grade_grade::get_hiding_affected($grades, $items);
-                        if (array_key_exists($course_item->id, $hiding_affected['altered'])) {
-                            $finalgrade = $hiding_affected['altered'][$course_item->id];
 
-                        } else if (!empty($hiding_affected['unknown'][$course_item->id])) {
-                            $finalgrade = null;
-                        }
-
-                        unset($hiding_affected);
-                        unset($grades);
-                        unset($items);
-                    }
-                }
-
                 $data = array($courselink, grade_format_gradevalue($finalgrade, $course_item, true));
 
                 if (!$this->showrank) {
@@ -224,6 +194,7 @@
 function grade_report_overview_settings_definition(&$mform) {
     global $CFG;
 
+    //show rank
     $options = array(-1 => get_string('default', 'grades'),
                       0 => get_string('hide'),
                       1 => get_string('show'));
@@ -236,6 +207,20 @@
 
     $mform->addElement('select', 'report_overview_showrank', get_string('showrank', 'grades'), $options);
     $mform->setHelpButton('report_overview_showrank', array('showrank', get_string('showrank', 'grades'), 'grade'));
+
+    //showtotalsifcontainhidden
+    $options = array(-1 => get_string('default', 'grades'),
+                      GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
+                      GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowhiddenitems', 'grades'));
+
+    if (empty($CFG->grade_report_overview_showtotalsifcontainhidden)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
 }
 
+    $mform->addElement('select', 'report_overview_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'), $options);
+    $mform->setHelpButton('report_overview_showtotalsifcontainhidden', array('hidetotalifhiddenitems', get_string('hidetotalifhiddenitems', 'grades'), 'grade'));
+}
+
 ?>
Index: moodle/grade/report/overview/settings.php
--- moodle/grade/report/overview/settings.php Base (1.1.2.3)
+++ moodle/grade/report/overview/settings.php Locally Modified (Based On 1.1.2.3)
@@ -19,4 +19,9 @@
 
 $settings->add(new admin_setting_configcheckbox('grade_report_overview_showrank', get_string('showrank', 'grades'), get_string('configshowrank', 'grades'), 0, PARAM_INT));
 
+$settings->add(new admin_setting_configselect('grade_report_overview_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'),
+                                                  get_string('hidetotalifhiddenitemsdescription', 'grades'), GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN,
+                                                  array(GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
+                                                        GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowhiddenitems', 'grades'))));
+
 ?>
Index: moodle/grade/report/user/lib.php
--- moodle/grade/report/user/lib.php Base (1.18.2.24)
+++ moodle/grade/report/user/lib.php Locally Modified (Based On 1.18.2.24)
@@ -99,6 +99,7 @@
         $this->showrank        = grade_get_setting($this->courseid, 'report_user_showrank', $CFG->grade_report_user_showrank);
         $this->showpercentage  = grade_get_setting($this->courseid, 'report_user_showpercentage', $CFG->grade_report_user_showpercentage);
         $this->showhiddenitems = grade_get_setting($this->courseid, 'report_user_showhiddenitems', $CFG->grade_report_user_showhiddenitems);
+        $this->showtotalsifcontainhidden = grade_get_setting($this->courseid, 'report_user_showtotalsifcontainhidden', $CFG->grade_report_user_showtotalsifcontainhidden);
 
         $this->showrange = true;
 
@@ -274,6 +275,10 @@
                     $data['grade']['content'] = '-';
                 } else {
                     $data['grade']['class'] = $class;
+
+                    // This is a really ugly hack, it will be fixed in 2.0
+                    $gradeval = $this->blank_hidden_total($this->courseid, $grade_grade->grade_item, $gradeval);
+
                     $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true);
                 }
 
@@ -461,8 +466,22 @@
 
     $mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options);
     $mform->setHelpButton('report_user_showhiddenitems', array('showhiddenitems', get_string('showhiddenitems', 'grades'), 'grade'));
+
+    //showtotalsifcontainhidden
+    $options = array(-1 => get_string('default', 'grades'),
+                      GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
+                      GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowhiddenitems', 'grades'));
+
+    if (empty($CFG->grade_report_user_showtotalsifcontainhidden)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
 }
 
+    $mform->addElement('select', 'report_user_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'), $options);
+    $mform->setHelpButton('report_user_showtotalsifcontainhidden', array('hidetotalifhiddenitems', get_string('hidetotalifhiddenitems', 'grades'), 'grade'));
+}
+
 function grade_report_user_profilereport($course, $user) {
     if (!empty($course->showgrades)) {
 
Index: moodle/grade/report/user/settings.php
--- moodle/grade/report/user/settings.php Base (1.1.2.7)
+++ moodle/grade/report/user/settings.php Locally Modified (Based On 1.1.2.7)
@@ -25,4 +25,9 @@
                  2 => get_string('showallhidden', 'grades'));
 $settings->add(new admin_setting_configselect('grade_report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), get_string('configshowhiddenitems', 'grades'), 1, $options));
 
+$settings->add(new admin_setting_configselect('grade_report_user_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'),
+                                                  get_string('hidetotalifhiddenitemsdescription', 'grades'), GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN,
+                                                  array(GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
+                                                        GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowhiddenitems', 'grades'))));
+
 ?>
Index: moodle/lang/en_utf8/grades.php
--- moodle/lang/en_utf8/grades.php Base (1.111.2.68)
+++ moodle/lang/en_utf8/grades.php Locally Modified (Based On 1.111.2.68)
@@ -24,7 +24,7 @@
 $string['aggregateoutcomes'] = 'Include outcomes in aggregation';
 $string['aggregateoutcomeshelp'] = 'Including outcomes in aggregation may not lead to the desired overall grade, so you have the option to include or leave them out.';
 $string['aggregatesubcats'] = 'Aggregate including subcategories';
-$string['aggregatesubcatshelp'] = 'The aggregation is usually done only with immediate children, it is also possible to aggregate grades in all subcategories excluding other aggregated grades.';
+$string['aggregatesubcatshelp'] = 'The aggregation is usually done only with immediate children, it is also possible to aggregate including individual grades in all subcategories excluding other aggregated grades.';
 $string['aggregatesum'] = 'Sum of grades';
 $string['aggregatesonly'] = 'Aggregates only';
 $string['aggregateweightedmean'] = 'Weighted mean of grades';
@@ -277,6 +277,9 @@
 $string['hidenooutcomes'] = 'Show outcomes';
 $string['hidefeedback'] = 'Hide feedback';
 $string['hideranges'] = 'Hide ranges';
+$string['hidetotalifhiddenitems'] = 'Hide total if it contains hidden items?';
+$string['hidetotalifhiddenitemsdescription'] = 'Hide the course/category total if it contains one or more hidden items?';
+$string['hidetotalshowhiddenitems'] = 'Show totals minus hidden items';
 $string['hideverbose'] = 'Hide $a->category$a->itemmodule $a->itemname';
 $string['highgradeascending'] = 'Sort by high grade ascending';
 $string['highgradedescending'] = 'Sort by high grade descending';
Index: moodle/lang/en_utf8/help/grade/aggregatesubcats.html
--- moodle/lang/en_utf8/help/grade/aggregatesubcats.html Base (1.1.2.1)
+++ moodle/lang/en_utf8/help/grade/aggregatesubcats.html Locally Modified (Based On 1.1.2.1)
@@ -1,2 +1,2 @@
 <h1>Aggregate including subcategories</h1>
-<p>The aggregation is usually done only with immediate children, it is also possible to aggregate grades in all subcategories excluding other aggregated grades.</p>
+<p>The aggregation is usually done only with immediate children, it is also possible to aggregate including individual grades in all subcategories excluding other aggregated grades.</p>
Index: moodle/lib/grade/constants.php
--- moodle/lib/grade/constants.php Base (1.7.2.4)
+++ moodle/lib/grade/constants.php Locally Modified (Based On 1.7.2.4)
@@ -79,6 +79,9 @@
 define('GRADE_REPORT_AGGREGATION_VIEW_AGGREGATES_ONLY', 1);
 define('GRADE_REPORT_AGGREGATION_VIEW_GRADES_ONLY', 2);
 
+define('GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN', 0);
+define('GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN', 1);
+
 define('GRADE_REPORT_PREFERENCE_DEFAULT', 'default'); // means use setting from site preferences
 define('GRADE_REPORT_PREFERENCE_INHERIT', 'inherit'); // means inherit from parent
 define('GRADE_REPORT_PREFERENCE_UNUSED', -1);
Index: moodle/lib/grade/grade_category.php
--- moodle/lib/grade/grade_category.php Base (1.96.2.30)
+++ moodle/lib/grade/grade_category.php Locally Modified (Based On 1.96.2.30)
Index: moodle/lib/grade/grade_grade.php
--- moodle/lib/grade/grade_grade.php Base (1.14.2.20)
+++ moodle/lib/grade/grade_grade.php Locally Modified (Based On 1.14.2.20)
@@ -590,10 +590,12 @@
         }
 
         $max = count($todo);
+        $hidden_precursors = null;
         for($i=0; $i<$max; $i++) {
             $found = false;
             foreach($todo as $key=>$do) {
-                if (array_intersect($dependson[$do], $unknown)) {
+                $hidden_precursors = array_intersect($dependson[$do], $unknown);
+                if ($hidden_precursors) {
                     // this item depends on hidden grade indirectly
                     $unknown[$do] = $do;
                     unset($todo[$key]);
@@ -601,7 +603,8 @@
                     continue;
 
                 } else if (!array_intersect($dependson[$do], $todo)) {
-                    if (!array_intersect($dependson[$do], array_keys($altered))) {
+                    $hidden_precursors = array_intersect($dependson[$do], array_keys($altered));
+                    if (!$hidden_precursors) {
                         // hiding does not affect this grade
                         unset($todo[$key]);
                         $found = true;
@@ -609,20 +612,22 @@
 
                     } else {
                         // depends on altered grades - we should try to recalculate if possible
-                        if ($grade_items[$do]->is_calculated() or (!$grade_items[$do]->is_category_item() and !$grade_items[$do]->is_course_item())) {
+                        if ($grade_items[$do]->is_calculated() or
+                            (!$grade_items[$do]->is_category_item() and !$grade_items[$do]->is_course_item())
+                        ) {
                             $unknown[$do] = $do;
                             unset($todo[$key]);
                             $found = true;
                             continue;
-
                         } else {
                             $grade_category = $grade_items[$do]->load_item_category();
 
                             $values = array();
                             foreach ($dependson[$do] as $itemid) {
                                 if (array_key_exists($itemid, $altered)) {
+                                    //nulling an altered precursor
                                     $values[$itemid] = $altered[$itemid];
-                                } elseif (!empty($values[$itemid])) {
+                                } elseif (empty($values[$itemid])) {
                                     $values[$itemid] = $grade_grades[$itemid]->finalgrade;
                                 }
                             }
Index: moodle/lib/grade/grade_object.php
--- moodle/lib/grade/grade_object.php Base (1.27.2.4)
+++ moodle/lib/grade/grade_object.php Locally Modified (Based On 1.27.2.4)
